package com.woniuxy.cloud.procurementassembly.service.Impl;

import cn.hutool.core.lang.generator.SnowflakeGenerator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.cloud.api.BatteryQueryApi;
import com.woniuxy.cloud.api.BatteryTypeApi;
import com.woniuxy.cloud.api.StorehouseQueryApi;
import com.woniuxy.cloud.api.UserQueryAPI;
import com.woniuxy.cloud.api.dto.UserDto;
import com.woniuxy.cloud.demo.Result;
import com.woniuxy.cloud.dto.BatteryTypeDto;
import com.woniuxy.cloud.dto.StorehouseDto;
import com.woniuxy.cloud.param.AddListBatteryParam;
import com.woniuxy.cloud.param.SaveBatteryParam;
import com.woniuxy.cloud.procurementassembly.dto.BatteryOrderDto;
import com.woniuxy.cloud.procurementassembly.entity.BatteryOrder;
import com.woniuxy.cloud.procurementassembly.entity.BatteryOrderDetails;
import com.woniuxy.cloud.procurementassembly.entity.BatteryOrderProcurementDetails;
import com.woniuxy.cloud.procurementassembly.exception.ProcurementException;
import com.woniuxy.cloud.procurementassembly.mapper.BatteryOrderMapper;
import com.woniuxy.cloud.procurementassembly.param.PayBatteryParam;
import com.woniuxy.cloud.procurementassembly.param.ReceiptParam;
import com.woniuxy.cloud.procurementassembly.param.SaveBatteryOrderParam;
import com.woniuxy.cloud.procurementassembly.param.UpdateBatteryOrderStatueParam;
import com.woniuxy.cloud.procurementassembly.service.BatteryOrderDetailsService;
import com.woniuxy.cloud.procurementassembly.service.BatteryOrderProcurementDetailsService;
import com.woniuxy.cloud.procurementassembly.service.BatteryOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.cloud.procurementassembly.util.WoniuBeanUtils;
import com.woniuxy.cloud.util.CreateNumberUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 周川雄
 * @since 2022-02-18
 */
@Service
public class BatteryOrderServiceImpl extends ServiceImpl<BatteryOrderMapper, BatteryOrder> implements BatteryOrderService {

    @Resource
    private UserQueryAPI userQueryAPI;
    @Resource
    private StorehouseQueryApi storehouseQueryApi;
    @Resource
    private BatteryTypeApi batteryTypeApi;
    @Resource
    private BatteryQueryApi batteryQueryApi;

    @Resource
    private BatteryOrderProcurementDetailsService service;
    @Resource
    private BatteryOrderDetailsService detailsService;

    /**
     * 采购电池
     *
     * @param param
     * @return
     */
    @GlobalTransactional
    @Override
    public BatteryOrderDto SaveBatteryOrder(SaveBatteryOrderParam param) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String userId = request.getHeader("userId");
        //先判断当前用户是否能处理这个,该用户是有这个仓库
        UserDto user = userQueryAPI.findUserById(Integer.valueOf(userId));

        Result<List<StorehouseDto>> storehosueByUserId = storehouseQueryApi.getStorehosueByUserId(Integer.valueOf(userId));
        List<StorehouseDto> data = storehosueByUserId.getData();

//        List<Integer> collect = data.stream().map(
//                id -> id.getStorehouseId()
//        ).collect(Collectors.toList());
//        if (!collect.contains(param.getStorehouseId())) throw new ProcurementException("该用户不能操控这个仓库", 10700);
        Map<Integer, StorehouseDto> StorehouseDtomaps = data.stream().collect(Collectors.toMap(StorehouseDto::getStorehouseId, Function.identity()));
         StorehouseDto storehouseDto = StorehouseDtomaps.get(param.getStorehouseId());
        if (StringUtils.isEmpty(storehouseDto))
            throw new ProcurementException("该用户不能操控这个仓库", 10700);

        //再判断电池数量类型是否正确

        List<Integer> typeIds = param.getList().stream().map(
                id -> id.getBatteryTypeId()
        ).collect(Collectors.toList());

        Result<List<BatteryTypeDto>> batteryType = batteryTypeApi.findBatteryType(typeIds);

        List<BatteryTypeDto> batteryTypeData = batteryType.getData();

        if (batteryTypeData != null && batteryTypeData.size() != typeIds.size())
            throw new ProcurementException("电池类型选择有误，请重新检查", 10701);

        Integer num = 0;
        Double price = 0.0;

        Map<Integer, BatteryTypeDto> maps = batteryTypeData.stream().collect(Collectors.toMap(BatteryTypeDto::getBatteryTypeId, Function.identity()));

        for (PayBatteryParam payBatteryParam : param.getList()) {
            num += payBatteryParam.getBatteryNum();
            price += maps.get(payBatteryParam.getBatteryTypeId()).getTypePrice() * payBatteryParam.getBatteryNum();
        }
        //生成订单

        Long next = new SnowflakeGenerator().next();
        String code = "CGDD" + next.toString();

        BatteryOrder order = BatteryOrder.builder().userId(user.getUserId()).userName(user.getUserName()).userPhone(user.getUserPhone())
                .orderStatus(0).orderApply(param.getOrderApply()).orderCountPrice(price).preordainCount(num).signCont(0)
                .storehouseId(param.getStorehouseId()).orderSource(param.getOrderSource()).storehouseName(storehouseDto.getStorehouseName())
                .storehouseLocation(storehouseDto.getLocation())
                .orderCode(code)

                .build();


        if (save(order)) {
            //生成订单详情
            ArrayList<BatteryOrderProcurementDetails> detailList = new ArrayList<>();

            for (PayBatteryParam batteryParam : param.getList()) {
                BatteryOrderProcurementDetails details = new BatteryOrderProcurementDetails();
                details.setOrderId(order.getOrderId());
                details.setOrderCode(code);
                details.setBatteryType(maps.get(batteryParam.getBatteryTypeId()).getTypeName());
                details.setBatteryTypeId(maps.get(batteryParam.getBatteryTypeId()).getBatteryTypeId());
                details.setBatteryCount(batteryParam.getBatteryNum());
                details.setBatteryPrice(maps.get(batteryParam.getBatteryTypeId()).getTypePrice());
                details.setOrderStatus(0);
                details.setBatteryRealCount(0);
                detailList.add(details);
            }

            if (service.saveBatch(detailList)) {
                return WoniuBeanUtils.copyObject(order, BatteryOrderDto.class);
            }
            throw new ProcurementException("生成采购详情失败", 10501);
        }

        throw new ProcurementException("生成订单失败", 10500);

    }

    @Override
    public BatteryOrderDto FindBatteryOrderByOrderId(Integer orderId) {
        BatteryOrder one = getOne(new QueryWrapper<BatteryOrder>().eq("order_del", 0).eq("order_id", orderId));
        return WoniuBeanUtils.copyObject(one, BatteryOrderDto.class);
    }

    @GlobalTransactional
    @Override
    public Boolean UpdateBatteryOrderStatue(UpdateBatteryOrderStatueParam param) {
//        只有没被删除,且状态为0提交才能审批
        BatteryOrder one = getOne(new QueryWrapper<BatteryOrder>()
                .eq("order_del", 0).eq("order_id", param.getOrderId()).eq("order_status", 0));

        if (StringUtils.isEmpty(one)) throw new ProcurementException("无订单存在，或者订单不属于可用审批的类型", 10702);
        one.setOrderStatus(param.getStatues());
        return updateById(one);
    }

    @GlobalTransactional
    @Override
    public BatteryOrderDto ReceiptParam(ReceiptParam param) {
        //只有审批成功的才进行收货
        BatteryOrder one = getOne(new QueryWrapper<BatteryOrder>()
                .eq("order_del", 0).eq("order_id", param.getOrderId()).eq("order_status", 1));
        if (StringUtils.isEmpty(one)) throw new ProcurementException("无订单存在，或者订单处于不能审批的类型", 10703);


        List<BatteryOrderProcurementDetails> list = service.list(new QueryWrapper<BatteryOrderProcurementDetails>().eq(
                "order_status", 0).eq("order_id", param.getOrderId()));
        if (StringUtils.isEmpty(list)) throw new ProcurementException("该订单无可完成的任务，请不要重复完成订单", 10704);
        //如果前端传过来的数据比数据库的数据更多，那么判断错误
        List<PayBatteryParam> batteryParams = param.getList();

        if (list.size() < batteryParams.size()) throw new ProcurementException("该订单没有购买这么多类型电池，请进行查核", 10707);

        Map<Integer, BatteryOrderProcurementDetails> maps = list.stream().collect(Collectors.toMap(BatteryOrderProcurementDetails::getBatteryTypeId, Function.identity()));
        //采购详情
        ArrayList<BatteryOrderProcurementDetails> details = new ArrayList<>();

        //收货详情
        ArrayList<BatteryOrderDetails> batteryOrderDetails = new ArrayList<>();


        Boolean b = true;
        Integer realCont = 0;
        Double preordainCount = 0.0;


        AddListBatteryParam addListBatteryParam = new AddListBatteryParam();


        List<SaveBatteryParam> batteryParamList = new ArrayList<SaveBatteryParam>();


        for (PayBatteryParam batteryParam : batteryParams) {


            BatteryOrderProcurementDetails batteryOrderProcurementDetails = maps.get(batteryParam.getBatteryTypeId());
            if (StringUtils.isEmpty(batteryOrderProcurementDetails))
                throw new ProcurementException("订单中无此电池存在，请检查数据", 10710);
            Integer batteryNum = batteryParam.getBatteryNum();
            Integer num = batteryOrderProcurementDetails.getBatteryRealCount() + batteryNum;
            if (num > batteryOrderProcurementDetails.getBatteryCount()) {
                throw new ProcurementException("该订单没有购买如此数量" + batteryOrderProcurementDetails.getBatteryType() + "电池,请查核数据", 10708);

            } else {

                //生成订单详情
                String code = "DC" + batteryOrderProcurementDetails.getBatteryTypeId() + "-3046-000";
                for (Integer i = 0; i < batteryNum; i++) {
                    BatteryOrderDetails orderDetails = new BatteryOrderDetails();
                    orderDetails.setOrderId(one.getOrderId());
                    orderDetails.setOrderCode(one.getOrderCode());
                    code = CreateNumberUtil.getNumber("DC", code);
                    orderDetails.setBateryCode(code);
                    orderDetails.setBatteryType(batteryOrderProcurementDetails.getBatteryType());
                    orderDetails.setBatteryPrice(batteryOrderProcurementDetails.getBatteryPrice());
                    orderDetails.setOrderStatus(0);
                    orderDetails.setOrderDel(0);
                    batteryOrderDetails.add(orderDetails);


                    SaveBatteryParam saveBatteryParam = new SaveBatteryParam();
                    saveBatteryParam.setBatteryTypeId(batteryOrderProcurementDetails.getBatteryTypeId());
                    saveBatteryParam.setTypeName(batteryOrderProcurementDetails.getBatteryType());
                    //入库
                    saveBatteryParam.setBatteryLocationLevel(0);
                    saveBatteryParam.setLocationId(one.getStorehouseId());
                    saveBatteryParam.setBatteryLocation(one.getStorehouseLocation());
                    saveBatteryParam.setBatteryCode(code);
                    batteryParamList.add(saveBatteryParam);
                }

                realCont += batteryNum;
                preordainCount += (batteryNum * batteryOrderProcurementDetails.getBatteryPrice());
                batteryOrderProcurementDetails.setBatteryRealCount(num);
                if (param.getIsReceipt() == 0) {
                    if (num == batteryOrderProcurementDetails.getBatteryCount()) {
                        //当电池数据足够，就设计为完成了任务
                        batteryOrderProcurementDetails.setOrderStatus(1);
                    } else if (num < batteryOrderProcurementDetails.getBatteryCount()) {
                        b = false;
                    }
                } else if (param.getIsReceipt() == 1) {
                    batteryOrderProcurementDetails.setOrderStatus(1);
                }

                details.add(batteryOrderProcurementDetails);
            }

        }
        //修改采购详情
        if (!service.updateBatchById(details)) throw new ProcurementException("修改采购详情失败", 10709);
        //修改订单详情

        if (b) {
            one.setOrderStatus(3);
        }

        one.setSignCont(one.getSignCont() + realCont);
        one.setOrderCountPrice(one.getOrderCountPrice() + preordainCount);
        if (!updateById(one)) throw new ProcurementException("修改订单失败", 10711);
//        preordain_count
        //先修改采购订单详情

        if (!detailsService.saveBatch(batteryOrderDetails)) throw new ProcurementException("生成采购订单详情失败", 10712);
        addListBatteryParam.setBatteryParams(batteryParamList);
        System.out.println("========================================" + batteryParamList);
        System.out.println("========================================" + addListBatteryParam);


        //电池入库
        batteryQueryApi.addBatteryList(addListBatteryParam);

        return WoniuBeanUtils.copyObject(one, BatteryOrderDto.class);

    }
}